home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 038a / edit_qb.zip / EDIT.ASM < prev    next >
Assembly Source File  |  1991-05-23  |  22KB  |  544 lines

  1. ;«RM92»«TS8,16,24,32,40,48»
  2. ; updated 5/21/91
  3.  
  4. DOSSEG
  5. .MODEL MEDIUM, BASIC
  6.  
  7. .DATA
  8.     EXTRN  B$TEMPDATA:WORD       ;inside FDATA, 128 byte buffer
  9.     EXTRN  B$STRINGLEN:WORD      ;inside FDATA, empty string descriptor
  10.     EXTRN  B$STRINGOFF:WORD      ;inside FDATA
  11.  
  12. .CODE
  13. EXTRN B$ASSN:FAR     ;This allows QBASIC to manipulate fixed length string
  14. EXTRN B$STDL:FAR     ;This creates null strings
  15.  
  16. ; Please do not remove
  17. Copyright       DB    13,10,'Copyright Copr. (C) 1991 Sidney J. Kelly',13,10
  18. Copyright1      DB    'All Rights Reserved',13,10,26
  19.  
  20. COPY_STRING_BUFFER      macro
  21. ;;Copies user input string to a buffer (FDATA.ASM)
  22. ;;Does not test length of string!
  23. ;;Uses SI,DI,ES,AX,CX,BX
  24. ;;Assumes BX = address of string descriptor
  25. ;;        CX = length of string
  26. ;;        DS = segment of string
  27. ;;        ES = DGROUP
  28. ;;        Direction Flag clear, CLD
  29. ;;Trashes AX, SI, DI and CX
  30.     Mov     SI,[BX+2]               ;; put offset of string in SI
  31.     Mov     DI,OFFSET B$TEMPDATA    ;; put address of buffer in DI
  32.     ;;Rep     MOVSB                   ;; copy the string to buffer
  33.     ;;The following is faster than a MOVSB routine
  34.     Shr     CX,1                    ;; convert bytes to word
  35.     Rep     MOVSW                   ;; move DS:SI to ES:DI
  36.     ADC     CX,CX                   ;; CX=1 if bytes were odd, 0 if even
  37.     Rep     MOVSB                   ;; copy the odd byte if there was one
  38. endm
  39.  
  40. ASCII_Space     EQU     32
  41.  
  42. EVEN
  43.     ;memory rather than stack used allow deep nesting of routine
  44.     ;prevents use under OS/2 or protected mode
  45.     Right_Edge      dw      0       ; right edge of Buffer
  46.     Max_Cursor      dw      0       ; dimension of max cursor
  47.     Min_Cursor      dw      0       ; dimension of min cursor
  48.     Orig_Cursor     dw      0       ; original cursor shape
  49.     Exit_Key        dw      0       ; key hit to exit routine
  50.     Old_BP          dw      0       ; temp storage for BP, to correct
  51.                     ; for bug in early PC video bios
  52.                     ; that changes BP
  53.  
  54.     Max_Len         db      0       ; max length of Result$
  55.     Curr_Page       db      0       ; current video page
  56.     Insert_State    db      0       ; -1 = insert on, 0 = insert off
  57.     Start_Row       db      0       ; Starting Row
  58.     Start_Col       db      0       ; Starting Column
  59.     Curr_Row        db      0       ; (never really used)
  60.     Curr_Col        db      0       ; Current column location
  61.     Max_Right       db      0       ; rightmost column
  62.     Curr_V_Mode     db      0       ; fix for rom BIOS error
  63.                     ; in AST 386/AMI 386 BIOS
  64.  
  65. ;=======================================================================
  66. ; DECLARE FUNCTION EDITOR$ (BYVAL ROW%, BYVAL COL%, BYVAL LENGTH%, _
  67. ; BYVAL ATTR%, INPUT$, FILTER$, EXITKEY%)
  68. ; Result$ = EDITOR$ (ROW%, COL%, LENGTH%, ATTR%, FILTER$, EXITKEY%)
  69. ; Compatible input editor, allowed keystrokes limited by Filter$.
  70. ; Extended keys not recognized, primarily for alpha-numeric input only
  71. ; Allows editing using any video page supported by the video system
  72. ;
  73. ; Editing keys recognized;
  74. ;    Home: move cursor to beginning of window
  75. ;    Insert; toggle insert mode, default mode is insert on
  76. ;    End; move cursor to end of window
  77. ;    Del: moves string left, deletes character under cursor
  78. ;    Backspace: moves string left, deletes character to left of cursor
  79. ;       Currently ESC, ENTER, TAB, and SHIFT-TAB will end the routine
  80. ;
  81. ; Input:
  82. ;    Row: Row on screen 1 to 50, no range check is performed
  83. ;    Col: Starting Column 1 to 80, no range check is performed
  84. ;       Length: Length of editing window, no range check performed
  85. ;               If extends past right border, then wraps to lower line.
  86. ;       Attr: Color attribute for window (back * 16 + foreground color)
  87. ;       Input$: allows programmer to feed routine an existing string
  88. ;               for editing.  The Input$ is not changed, only Result$ is.
  89. ;    Filter$: the input filter string, if LEN(Filter$) = 0 then
  90. ;        every key is o.k.
  91. ;    Exitkey%: the scan code of the key used to exit the routine
  92. ;               currently ESC, ENTER, TAB, and SHIFT-TAB recognized
  93. ;=======================================================================
  94.  
  95. EVEN
  96. EDITOR  PROC FAR BASIC USES SI DI, ROW:WORD, COL:WORD, \
  97. LENGTHH:WORD, ATTR:WORD, INPUT:WORD, FILTER:WORD, EXITKEY:WORD
  98.  
  99.     Assume DS:@data
  100. Setup:
  101.     Mov     Old_BP,BP       ; store it because bios may change BP
  102.                 ; and we need it to access stack correctly
  103.     Mov     AX,@data        ; this is a pointer to DGROUP
  104.     Mov     ES,AX           ; move near data seg to ES
  105.     Assume  ES:@data        ; tell assembler
  106.     CLD                     ; clear direction flag for safety
  107.     Mov     AX,2020h        ; load spaces in AX
  108.     Mov     CX,44           ; count 44 words, 88 bytes to be safe
  109.     Mov     DI,OFFSET B$TEMPDATA  ; load offset of buffer in DI
  110.     Rep     STOSW           ; fill buffer (ES:DI) with spaces
  111.     Mov     AL,0FFh         ; make AL = -1 to record using insert mode
  112.     Mov     Insert_State,AL
  113.     Mov     AX,LENGTHH      ; get length of output string into AX (BYVAL)
  114.     Or      AX,AX           ; make sure not 0
  115.     JNZ     Setup1          ; not 0, so jump ahead
  116.     Mov     AX,1            ; make AX = 1, so can read one character
  117.     Jmp     Short  Setup2   ; jump ahead
  118.  
  119. Setup1:
  120.     Cmp     AL,80           ; make sure LENGTHH < than size of buffer
  121.     JBE     Setup2          ; range o.k. so continue
  122.     Mov     AL,80           ; else make it 80 character max
  123.  
  124. Setup2:
  125.     Mov     Max_Len,AL      ; store in CSEG
  126.     Mov     BL,AL           ; store temporarily in BL
  127.     Dec     BL              ; make length 0 biased
  128.     Mov     AX,ROW          ; get starting row into AX (BYVAL)
  129.     Dec     AL              ; make 0 bias
  130.     Mov     Start_Row,AL    ; store value
  131.     Mov     Curr_Row,AL     ; put cursor at beginning
  132.     Mov     AX,COL          ; get starting column into AX (BYVAL)
  133.     Dec     AL              ; make 0 bias
  134.     Mov     Start_Col,AL    ; store value
  135.     Mov     Curr_Col,AL     ; put cursor at beginning
  136.     Add     AL,BL           ; add Curr_Col+(Max_Len-1)
  137.     Mov     Max_Right,AL    ; store in Max_Right
  138.     Mov     AX,OFFSET B$TEMPDATA  ; load offset of buffer in AX
  139.     Add     AL,BL           ; add 0 biased length to buffer offset
  140.     Mov     Right_Edge,AX   ; store in memory for fast access
  141.  
  142. Get_Video_Info:
  143.  
  144.     Mov     AH,0Fh          ; get current page number in BH
  145.     Int     10h
  146.     Mov     Curr_Page,BH    ; save current page number
  147.     Mov    Curr_V_Mode,AL    ; save current video mode
  148.     Cmp    AL,7        ; mono mode?
  149.     JNE    Try_Color    ; nope, try color
  150.     Mov    AH,3        ; get current default size
  151.     Int    10h
  152.     Mov     Orig_Cursor,CX  ; save current cursor shape
  153.     Mov    CX,000Ch    ; use mono sizing
  154.     Mov    Max_Cursor,CX    ; set max cursor size
  155.     Mov    AH,1        ; to model insert mode
  156.     Int    10h
  157.     Mov    CH,0Bh        ; set min cursor size for mono
  158.     Mov    Min_Cursor,CX    ; save it
  159.     Jmp Short Other_Info    ; skip over color sections
  160.     
  161. Try_Color:
  162.     Mov     AH,3            ; BH must contain current page number
  163.     Int     10h             ; returns current cursor in CX
  164.     Mov     Orig_Cursor,CX  ; save current cursor shape
  165.     Mov     DX,CX           ; copy value in DX too for temporary storage
  166.     Xor     CH,CH           ; clear top value so it is 0
  167.     Mov     Max_Cursor,CX   ; store maximum size in CSEG
  168.     Mov     AH,1        ; AL contains current video mode
  169.     Int     10h             ; set cursor to maximum size
  170.     Mov     CL,DL           ; get back temporary value from DX
  171.     Mov     CH,DL
  172.     Dec     CH              ; reduce top scan value by one
  173.     Mov     Min_Cursor,CX   ; store in Min value
  174.  
  175. Other_Info:
  176.     Call    Near Ptr Mov_Cursor    ; move cursor where desired
  177.     Mov     BP,Old_BP       ; restore BP in case bios changed it
  178.     Mov     AX,ATTR         ; get attribute in AX (BYVAL)
  179.     Or      AX,AX           ; see if it is zero
  180.     JNZ     @f
  181.     Mov     AL,7            ; use default of White on Black
  182. @@:
  183.     Mov     BL,AL           ; put display attribute in BL
  184.                 ; BH already contains current page
  185.     Mov     AX,0920h        ; get ready to print spaces
  186.     Mov     CL,Max_Len      ; write spaces on screen
  187.     Xor     CH,CH           ; print spaces using function 9
  188.     Int     10h             ; as this allows us to set attributes
  189.                 ; but it does not move cursor
  190.                 ; so this is the only time we use it
  191.     Mov     DL,CL           ; store Max_Len in DL
  192.     Xor     DH,DH           ; clear DH
  193.     Mov     BP,Old_BP       ; restore BP in case bios changed it
  194.     Mov     BX,INPUT        ; get address of input string
  195.     Mov     CX,[BX]         ; get length in CX
  196.     JCXZ    Clear_Keyb      ; if LEN=0 then skip ahead
  197.     Cmp     CX,DX           ; is LEN > Max_Len
  198.     JBE     @f              ; it is less than or equal so jump ahead
  199.     Mov     CX,DX           ; make LEN of Imput$ = Max_Len
  200. @@:
  201.     Mov     DX,CX           ; store LEN in DX, because CX will be trashed
  202.     COPY_STRING_BUFFER      ; copy Input$ to buffer MACRO
  203.     Mov     AL,Curr_Col     ; get starting column
  204.     Add     AL,DL           ; add LEN to Start_Row
  205.     Mov     BL,Max_Right    ; get address of right side
  206.     Cmp     AL,BL           ; see if AL > Max_Right
  207.     JBE     @f              ; if less than or equal, skip ahead
  208.     Mov     AL,BL           ; limit cursor to right side of buffer
  209. @@:
  210.     Mov     Curr_Col,AL     ; move cursor to end of string
  211.     Call    Near Ptr Show_String    ; show input string
  212.  
  213. EVEN
  214. Clear_Keyb:
  215.     ; make sure buffer is empty when we start
  216.     ; there are faster ways, but this is the most compatible way
  217.     ; faster way will be incompatible with Tandy machines
  218.  
  219.     Mov     AH,1            ; clear keyboard buffer
  220.     Int     16h
  221.     JZ      Main            ; no key waiting so quit
  222.     Xor     AH,AH           ; get key into AX
  223.     Int     16h
  224.     Jmp     Short Clear_Keyb  ; loop until buffer is empty
  225.  
  226. EVEN
  227. Main:    ; this is the main loop, most everything returns here
  228.     Xor     AH,AH           ; this will wait until a key is pressed
  229.     Int     16h             ; use BIOS so CTRL-C, CTRL-BREAK wont
  230.                 ; kill program
  231.     Or      AL,AL           ; is it an extended key?
  232.     JZ      Parse_Extended  ; yes
  233.     Cmp     AL,ASCII_Space  ; below ASCII 32 (space character)
  234.     JB      Parse_Control   ; yes, treat as control key
  235.     Mov     BP,Old_BP       ; restore BP in case bios changed it
  236.     Mov     BX,FILTER       ; check if an allowed key
  237.     Mov     CX,[BX]         ; move length ito CX, if LEN(FILTER$) = 0
  238.     Jcxz    Add_String      ; then, by definition, got the right key
  239.     Mov     DI,ES:[BX+2]    ; move address of FILTER$ to DI
  240.     Repne   Scasb           ; search for match
  241.     JNE     Err_Beep        ; did we search entire string?, if yes Beep
  242.  
  243. Add_String:
  244.     Jmp     Add_Char        ; add AL to string buffer & display it
  245.  
  246. EVEN
  247. Err_Beep:
  248.     Mov     AX, 0E07h       ; Write ASCII 7 character
  249.     Int     10h             ; (bell) to console (BEEP)
  250.     ; this makes the beep CPU speed independent
  251.     Jmp     Short Clear_Keyb; clear KBD buffer to prevent excess keys
  252.  
  253. EVEN
  254. Parse_Control:                          ; parse control keys
  255.     Mov     Exit_Key,AX             ; store exit key in CSEG buffer
  256.     Cmp     AL,9                    ; Is it a tab key?
  257.     JE      Quit1                   ; yes, so quit
  258.     Cmp     AL,13                   ; Is it a carriage return key?
  259.     JE      Quit1                   ; yes, so quit
  260.     Cmp     AL,27                   ; Is it an escape key?
  261.     JE      Quit1                   ; yes, so quit
  262.     Cmp     AL,8                    ; Is it backspace?
  263.     JNE     Main                    ; not any of the above so reloop
  264.  
  265.     ; Send   BackSpace              ; else, send backspace
  266.     Mov     AL,Curr_Col             ; get current column
  267.     Cmp     AL,Start_Col            ; see > starting column
  268.     JA      Back_S                  ; it is, so o.k.
  269.     Jmp     Err_Beep                ; else, at left margin can go no more
  270.  Back_S:
  271.     Dec     AL                      ; reduce current column by one
  272.     Mov     Curr_Col,AL             ; store result
  273.     Call Near Ptr Mov_Buff_Left     ; move buffer left
  274.     Call Near Ptr Show_String       ; display changes
  275.     Jmp     Main
  276.  
  277. EVEN
  278. Quit1:                                  ; lilly pad
  279.     Jmp     Quit
  280.  
  281. EVEN
  282. Parse_Extended:                         ; parse extended keys
  283.     Mov     Exit_Key,AX             ; store exit key in CSEG buffer
  284.     Cmp     AH,15                   ; is it shift-tab
  285.     JE      Quit1                   ; yes, so quit
  286.     Cmp     AH,52h                  ; is it Insert
  287.     JNE     @f                      ; nope, so jump ahead
  288.  
  289.   Toggle_Insert:                        ; Toggle Insert mode
  290.     Mov     AL,Insert_State         ; get current state
  291.     Not     AL                      ; flip all bits 0 to FFh, or FFh to 0
  292.     Mov     Insert_State,AL         ; store current result
  293.     Mov     CX,Max_Cursor           ; assume max cursor size
  294.     Or      AL,AL                   ; is AL = 0, want min size?
  295.     JNZ     Tog_1                   ; nope, wanted max size
  296.     Mov     CX,Min_Cursor           ; else get min cursor
  297.   Tog_1:
  298.     Mov     AH,1                    ; set current scan lines
  299.     Mov     AL,Curr_V_Mode          ; fix AST/AMI 386 Rom BIOS error
  300.     Int     10h
  301.     Jmp     Main                    ; hop back to main loop
  302.  
  303. @@:
  304.     Cmp     AH,4Dh                  ; is it right arrow
  305.     JNE     @f                      ; not a special key so continue
  306.  
  307.   Mov_Right:                            ; Move cursor right
  308.     Mov     AL,Curr_Col             ; get current column
  309.     Cmp     AL,Max_Right            ; get right border
  310.     JB      Mov_R                   ; are we left of right border
  311.     Jmp     Err_Beep                ; nope, so beep
  312.   Mov_R:
  313.     Inc     AL                      ; move current column right
  314.     Mov     Curr_Col,AL             ; update memory variable
  315.     Call    Near Ptr Mov_Cursor     ; move cursor where desired
  316.     Jmp     Main
  317.  
  318. @@:
  319.     Cmp     AH,4Bh                  ; is it a left arrow
  320.     JNE     @f                      ; not that key so continue
  321.  
  322.   Mov_Left:                             ; Move cursor left
  323.     Mov     AL,Curr_Col
  324.     Cmp     AL,Start_Col            ; are we right of left border
  325.     JA      Mov_L
  326.     Jmp     Err_Beep                ; nope, so beep
  327.   Mov_L:
  328.     Dec     AL
  329.     Mov     Curr_Col,AL
  330.     Call    Near Ptr Mov_Cursor     ; move cursor where desired
  331.     Jmp     Main
  332.  
  333. @@:
  334.     Cmp     AH,47h                  ; is it the home key
  335.     JNE     @f                      ; not that key so continue
  336.  
  337.   Mov_Home:                             ; Cursor Home, to start of string
  338.     Mov     AL,Start_Col            ; get starting column
  339.     Mov     Curr_Col,AL             ; make current column = starting
  340.     Call    Near Ptr Mov_Cursor     ; move cursor where desired
  341.     Jmp     Main                    ; hop back into main loop
  342.  
  343. @@:
  344.     Cmp     AH,53h                  ; is it Del key
  345.     JNE     @f                      ; not that key so continue
  346.  
  347.   Del_Char:                             ; else, delete current character
  348.     Call Near Ptr Mov_Buff_Left     ; move string at right of cursor, left
  349.     Call Near Ptr Show_String       ; but don't move cursor
  350.     Jmp     Main
  351.  
  352. @@:
  353.     Cmp     AH,4Fh                  ; is it the end key?
  354.     JE      Mov_End                 ; yes
  355.     Jmp     Main                    ; nope so start again
  356.  
  357.   Mov_End:                              ; Move to End of buffer
  358.     Mov     AL,Max_Right
  359.     Mov     Curr_Col,AL
  360.     Call  Near Ptr  Mov_Cursor      ; move cursor where desired
  361.     Jmp     Main
  362.  
  363. EVEN
  364. Quit:
  365.     Mov     AH,1                    ; reset cursor to original size
  366.     Mov     AL,Curr_V_Mode          ; fix AST/AMI 386 Rom BIOS error
  367.     Mov     CX,Orig_Cursor
  368.     Int     10h
  369.     Mov     BP,Old_BP               ; restore BP in case bios changed it
  370.     Mov     BX,EXITKEY              ; get address of EXITKEY
  371.     Mov     AX,Exit_Key             ; save ExitKey
  372.     Or      AL,AL                   ; make sure return value in AL
  373.     JNZ     @f
  374.     Mov     AL,AH                   ; if not then move to AL
  375. @@:
  376.     Xor     AH,AH                   ; and make sure that AH = 0
  377.     Mov     [BX],AX                 ; store in EXITKEY
  378.  
  379. CopyString:
  380.     Mov     AL,Max_Len              ; get length of string in AX
  381.     Xor     AH,AH                   ; clear high byte
  382.     Mov     CX,AX                   ; put length in CX
  383.     Mov     DI,OFFSET B$TEMPDATA    ; move address of string to DI
  384.     Dec     AX                      ; make Max_Len zero biased
  385.     Add     DI,AX                   ; get last byte (beginning + length)
  386.     Mov     AL,20h                  ; look for trailing spaces
  387.     STD                             ; set direction down, scan backwards
  388.     Repz    Scasb                   ; search for non match (ES:DI w/ AL)
  389.     CLD                             ; clear direction flag
  390.     JZ      Err_Quit                ; all spaces so quit
  391.     Inc     CX                      ; remove 1 byte overrun of SCASB
  392.  
  393. ; standard way to return a string to QBASIC
  394.     Push    DS                      ; Store the Data Segment
  395.     Mov     AX, OFFSET B$TEMPDATA
  396.     Push    AX                      ; Store offset of string
  397.     Push    CX                      ; Store LENGTH of string
  398.     Push    DS                      ; Store the Data Segment
  399.     Mov     AX, OFFSET B$STRINGLEN
  400.     Push    AX                      ; Store Descriptor of string
  401.     Xor     AX,AX                   ; tell Basic it is a variable string
  402.     Push    AX                      ; Store a 0
  403.     Call    B$ASSN                  ; copy string into BASIC space
  404.     Mov     AX, OFFSET B$STRINGLEN  ; address of descriptor
  405.     Ret
  406.  
  407. EVEN
  408. Err_Quit:
  409.     ; this returns a null string if have an error
  410.     Mov     AH,1            ; reset cursor to original size
  411.     Mov     CX,Orig_Cursor
  412.     Mov     AL,Curr_V_Mode          ; fix AST/AMI 386 Rom BIOS error
  413.     Int     10h
  414.  
  415. Err_Quit1:
  416.     Mov     BP,Old_BP               ; restore BP in case bios changed it
  417.     Mov     BX,EXITKEY
  418.     Xor     AX,AX                ; return no exit key
  419.     Mov     [BX],AX
  420.     Mov     AX, OFFSET B$STRINGLEN  ; put address of
  421.     Push    AX                      ; descriptor in AX
  422.     Call    B$STDL                  ; make it a null string
  423.     Mov     AX, OFFSET B$STRINGLEN  ; put address of descriptor in AX
  424.     Ret
  425. EDITOR ENDP
  426.  
  427. ;--------------------------- Jump Section-------------------------
  428. ;simple procedures with local labels so that they will not have public names
  429. ;and take up space in the .OBJ file with use full PROC directives
  430.  
  431. EVEN
  432. Mov_Cursor  Label Near                  ; this is a common routine
  433.     Mov     DH,Curr_Row             ; move cursor to that location
  434.     Mov     DL,Curr_Col             ; Row at Curr_Row, Col at Curr_Col
  435.     Mov     BH,Curr_Page            ; this allows use of any video page
  436.     Mov     AH,2
  437.     Int     10h
  438.     Retn
  439.  
  440.  
  441. EVEN
  442. Show_String  Label Near
  443.     ; turn off cursor until printing is complete
  444.     Mov     BH,Curr_Page            ; get current page in BH
  445.     Mov     AH,3                    ; read cursro info
  446.     Int     10h                     ; Clear cursor by
  447.     Or      CH,20h                  ; by turning on bit 5 of CH
  448.     Mov     AH,1                    ; set Cursor size function
  449.     Mov     AL,Curr_V_Mode          ; fix AST/AMI 386 Rom BIOS error
  450.     Int     10h                     ; do it
  451.  
  452.     Mov     AH,2                    ; move cursor to beginning of string
  453.     Mov     DH,Start_Row            ; note BH contains Curr_Page
  454.     Mov     DL,Start_Col            ; load starting Row & Column
  455.     Int     10h
  456.  
  457.     Mov     CL,Max_Len              ; determine how many bytes to show
  458.     Xor     CH,CH                   ; clear CH
  459.     Mov     SI,OFFSET B$TEMPDATA    ; get the offset of buffer into SI
  460. EVEN
  461. Looper1:
  462.     Lodsb                           ; load DS:SI into AL
  463.     Mov     AH,0Eh                  ; display AL & move cursor
  464.     Int     10h                     ; (now hidden)
  465.     Loop    Looper1
  466.  
  467.     Mov     AH,3                    ; make cursor visable again
  468.     Int     10h                     ; get current cursor
  469.     And     CH,11011111b            ; clear bit 5
  470.     Mov     AH,1                    ; reset cursor so it is now displays
  471.     Mov     AL,Curr_V_Mode          ; fix AST/AMI 386 Rom BIOS error
  472.     Int     10h
  473.     Jmp     Mov_Cursor              ; move cursor to desired location
  474.                     ; & return from whence we came
  475.  
  476. EVEN
  477. Add_Char  Label Near
  478.     Mov     CX,AX                   ; temporarily store AX in CX
  479.     Mov     AL,Insert_State         ; see if Insert Mode is on
  480.     Cmp     AL,0                    ; i.e. is AL <> 0?
  481.     JE      Add_Char1               ; nope, AL = 0 insert off, skip ahead
  482.     Mov     AL,Curr_Col             ; get current location
  483.     Cmp     Max_Right,AL            ; are we at right column edge?
  484.     JE      Add_Char1               ; yes so add to buffer, & ignore Insert mode
  485.  
  486.  Mov_Buff_Right:
  487.     ; must preserve CX
  488.     Mov     DX,CX                   ; store CX in DX to preserve CX
  489.     Mov     BX,Right_Edge           ; load BX w/ right side of buffer
  490.     Mov     DI,BX                   ; set destination in ES:DI
  491.     Dec     BX                      ; reduce right side by one
  492.     Mov     SI,BX                   ; set source in DS:SI
  493.     Mov     AL,Curr_Col             ; find how many words to
  494.     Mov     CL,Max_Right            ; right of cursor
  495.     Sub     CL,AL
  496.     Inc     CL                      ; remove 0 bias
  497.     Xor     CH,CH                   ; number of bytes in CX
  498.     Std                ; use STD to count down
  499.     Rep     MovSB
  500.     Cld                             ; reset flag
  501.     Mov     CX,DX                   ; restore CX to original value
  502.  
  503. Add_Char1:
  504.     Mov     SI, OFFSET B$TEMPDATA   ; get address of buffer in SI
  505.     Mov     AL,Start_Col
  506.     Mov     BL,Curr_Col
  507.     Sub     BL,AL
  508.     Xor     BH,BH
  509.     Mov     DS:[SI+BX],CL
  510.     Call Near Ptr Show_String
  511.     Mov     AL,Curr_Col
  512.     Cmp     AL,Max_Right
  513.     JB      Add_Char2
  514.     Jmp     Main
  515. Add_Char2:
  516.     Inc     AL                      ; increment the cursor location
  517.     Mov     Curr_Col,AL
  518.     Call Near Ptr Mov_Cursor    ; move cursor where desired
  519.     Jmp     Main                    ; start loop again
  520.  
  521. EVEN
  522. Mov_Buff_Left  Label Near
  523.     ; moves the buffer left to erase a character or characters
  524.     Mov     BX,OFFSET B$TEMPDATA
  525.     Mov     AL,Start_Col
  526.     Mov     CL,Curr_Col
  527.     Sub     CL,AL
  528.     Xor     CH,CH
  529.     Add     BX,CX
  530.     Mov     DI,BX                   ; put destination in ES:DI
  531.     Inc     BX
  532.     Mov     SI,BX                   ; put source in DS:SI
  533.     Mov     CL,Max_Right
  534.     Mov     AL,Curr_Col
  535.     Sub     CL,AL
  536.     Inc     CL                      ; find how many words to move
  537.     Rep     MovSB
  538.     Mov     BX,Right_Edge           ; get right side of buffer
  539.     Mov     AL,ASCII_Space          ; put ASCII space in AL
  540.     Mov     DS:[BX],AL              ; add ASCII space to end of string
  541.     Retn
  542. END
  543.  
  544.